<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五子棋游戏</title>
    <style>
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            font-family: Arial, sans-serif;
            background-color: #f5f5f5;
            margin: 0;
            padding: 20px;
        }
        
        h1 {
            color: #333;
            margin-bottom: 20px;
        }
        
        #game-container {
            position: relative;
            margin-bottom: 20px;
        }
        
        #board {
            background-color: #dcb35c;
            border: 2px solid #8d6e3b;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
        }
        
        #status {
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 10px;
            height: 24px;
        }
        
        button {
            padding: 8px 16px;
            font-size: 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
        
        button:hover {
            background-color: #45a049;
        }
        
        .controls {
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h1>五子棋游戏</h1>
    <div id="status">黑方回合</div>
    <div id="game-container">
        <canvas id="board" width="450" height="450"></canvas>
    </div>
    <div class="controls">
        <button id="restart">重新开始</button>
    </div>

    <script>
        // 游戏常量
        const BOARD_SIZE = 15;  // 15x15的棋盘
        const CELL_SIZE = 30;    // 每个格子的大小
        const PIECE_RADIUS = 13; // 棋子半径
        
        // 游戏状态
        let board = [];         // 棋盘状态数组
        let currentPlayer = 1;  // 1: 黑棋, 2: 白棋
        let gameOver = false;   // 游戏是否结束
        
        // 获取DOM元素
        const canvas = document.getElementById('board');
        const ctx = canvas.getContext('2d');
        const statusDisplay = document.getElementById('status');
        const restartButton = document.getElementById('restart');
        
        // 初始化游戏
        function initGame() {
            // 初始化棋盘数组
            board = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0));
            
            currentPlayer = 1;
            gameOver = false;
            statusDisplay.textContent = "黑方回合";
            
            // 绘制棋盘
            drawBoard();
        }
        
        // 绘制棋盘
        function drawBoard() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制棋盘背景
            ctx.fillStyle = '#dcb35c';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格线
            ctx.strokeStyle = '#000';
            ctx.lineWidth = 1;
            
            for (let i = 0; i < BOARD_SIZE; i++) {
                // 横线
                ctx.beginPath();
                ctx.moveTo(CELL_SIZE / 2, i * CELL_SIZE + CELL_SIZE / 2);
                ctx.lineTo(canvas.width - CELL_SIZE / 2, i * CELL_SIZE + CELL_SIZE / 2);
                ctx.stroke();
                
                // 竖线
                ctx.beginPath();
                ctx.moveTo(i * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE / 2);
                ctx.lineTo(i * CELL_SIZE + CELL_SIZE / 2, canvas.height - CELL_SIZE / 2);
                ctx.stroke();
            }
            
            // 绘制天元和星位
            drawStarPoint(3, 3);
            drawStarPoint(3, 11);
            drawStarPoint(7, 7);
            drawStarPoint(11, 3);
            drawStarPoint(11, 11);
            
            // 绘制已有棋子
            for (let y = 0; y < BOARD_SIZE; y++) {
                for (let x = 0; x < BOARD_SIZE; x++) {
                    if (board[y][x] !== 0) {
                        drawPiece(x, y, board[y][x]);
                    }
                }
            }
        }
        
        // 绘制星位
        function drawStarPoint(x, y) {
            ctx.fillStyle = '#000';
            ctx.beginPath();
            ctx.arc(
                x * CELL_SIZE + CELL_SIZE / 2,
                y * CELL_SIZE + CELL_SIZE / 2,
                3,
                0,
                Math.PI * 2
            );
            ctx.fill();
        }
        
        // 绘制棋子
        function drawPiece(x, y, player) {
            const centerX = x * CELL_SIZE + CELL_SIZE / 2;
            const centerY = y * CELL_SIZE + CELL_SIZE / 2;
            
            // 绘制棋子阴影
            ctx.beginPath();
            ctx.arc(centerX, centerY, PIECE_RADIUS, 0, Math.PI * 2);
            
            const gradient = ctx.createRadialGradient(
                centerX - 3, centerY - 3, PIECE_RADIUS / 3,
                centerX, centerY, PIECE_RADIUS
            );
            
            if (player === 1) {  // 黑棋
                gradient.addColorStop(0, '#666');
                gradient.addColorStop(1, '#000');
            } else {  // 白棋
                gradient.addColorStop(0, '#fff');
                gradient.addColorStop(1, '#ddd');
            }
            
            ctx.fillStyle = gradient;
            ctx.fill();
            
            // 棋子高光效果
            if (player === 1) {
                ctx.beginPath();
                ctx.arc(centerX - 4, centerY - 4, 3, 0, Math.PI * 2);
                ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
                ctx.fill();
            }
        }
        
        // 放置棋子
        function placePiece(x, y) {
            if (gameOver || board[y][x] !== 0) {
                return false;
            }
            
            board[y][x] = currentPlayer;
            drawPiece(x, y, currentPlayer);
            
            // 检查胜负
            if (checkWin(x, y, currentPlayer)) {
                gameOver = true;
                const winner = currentPlayer === 1 ? "黑方" : "白方";
                statusDisplay.textContent = `${winner}获胜！`;
                return true;
            }
            
            // 切换玩家
            currentPlayer = currentPlayer === 1 ? 2 : 1;
            statusDisplay.textContent = currentPlayer === 1 ? "黑方回合" : "白方回合";
            return true;
        }
        
        // 检查是否获胜
        function checkWin(x, y, player) {
            const directions = [
                [1, 0],   // 水平
                [0, 1],   // 垂直
                [1, 1],   // 对角线
                [1, -1]   // 反对角线
            ];
            
            for (const [dx, dy] of directions) {
                let count = 1;  // 当前棋子已经算一个
                
                // 正向检查
                count += countInDirection(x, y, dx, dy, player);
                // 反向检查
                count += countInDirection(x, y, -dx, -dy, player);
                
                if (count >= 5) {
                    return true;
                }
            }
            
            return false;
        }
        
        // 计算某个方向上的连续棋子数
        function countInDirection(x, y, dx, dy, player) {
            let count = 0;
            let newX = x + dx;
            let newY = y + dy;
            
            while (
                newX >= 0 && newX < BOARD_SIZE &&
                newY >= 0 && newY < BOARD_SIZE &&
                board[newY][newX] === player
            ) {
                count++;
                newX += dx;
                newY += dy;
            }
            
            return count;
        }
        
        // 处理鼠标点击事件
        function handleClick(event) {
            const rect = canvas.getBoundingClientRect();
            const mouseX = event.clientX - rect.left;
            const mouseY = event.clientY - rect.top;
            
            // 计算点击的棋盘坐标
            const x = Math.round((mouseX - CELL_SIZE / 2) / CELL_SIZE);
            const y = Math.round((mouseY - CELL_SIZE / 2) / CELL_SIZE);
            
            // 检查坐标是否有效
            if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE) {
                placePiece(x, y);
            }
        }
        
        // 事件监听
        canvas.addEventListener('click', handleClick);
        restartButton.addEventListener('click', initGame);
        
        // 开始游戏
        initGame();
    </script>
</body>
</html>